/**
 * Copyright &copy; 2020 <a href="https://github.com/somowhere/exam-system">exam-system</a> All rights reserved.
 */
package com.shanhesoft.java.modules.exam.web;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.shanhesoft.java.common.core.constant.CommonConstants;
import com.shanhesoft.java.common.core.util.Result;
import com.shanhesoft.java.common.core.vo.PageModel;
import com.shanhesoft.java.common.data.util.QueryWrapperUtil;
import com.shanhesoft.java.common.web.resource.BaseResource;
import com.shanhesoft.java.modules.exam.domain.Answer;
import com.shanhesoft.java.modules.exam.domain.PaperQue;
import com.shanhesoft.java.modules.exam.domain.dto.*;
import com.shanhesoft.java.modules.exam.service.*;

import lombok.extern.slf4j.Slf4j;
import io.swagger.annotations.ApiOperation;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import lombok.AllArgsConstructor;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 答题信息Controller 答题信息
 * @author admin
 * @version 2020-10-12 23:59:25
 */
@RestController
@RequestMapping(value = "${application.admin-path}/exam/answer")
@Slf4j
@AllArgsConstructor
public class AnswerResource extends BaseResource {

	private final AnswerService service;
	private final TBankFillQueService fillQueService;
	private final TBankJudgeQueService judgeQueService;
	private final TBankSingleChoiceQueService singleChoiceQueService;
	private final TBankMultipleChoiceQueService multipleChoiceQueService;
	private final OjProblemsService ojProblemsService;
	private final ExaminationRecordService recordService;
	private final PaperQueService paperQueService;

	/**
	 * @param id
	 * @return
	 */
	@GetMapping(CommonConstants.URL_ID_REGEX)
	@PreAuthorize("@pms.hasPermission('exam_answer_view')")
	public Result get(@PathVariable String id) {
		log.debug("REST request to get Entity : {}", id);
		return  Result.buildOkData(service.getOneDto(id));
	}
	/**
	 * GET / : get all answer.
	 *
	 * @param pm the pagination information
	 * @return the Result with status 200 (OK) and with body all answer
	 */

	@PreAuthorize("@pms.hasPermission('exam_answer_view')")
	@GetMapping
	@ApiOperation(value = "答题信息查看")
	public Result getPage(PageModel pm, AnswerQueryCriteria answerQueryCriteria) {
		QueryWrapper wrapper = QueryWrapperUtil.getWrapper(pm, answerQueryCriteria);
		return Result.buildOkData(service.page(pm, wrapper));
	}

	/**
	 * POST / : Save a answerDto.
	 *
	 * @param answerDto the HTTP answer
	 */
	@PreAuthorize("@pms.hasPermission('exam_answer_edit')")
	@ApiOperation(value = "答题信息编辑")
	@PostMapping
	public Result save(@Valid @RequestBody AnswerDto answerDto) {
		log.debug("REST request to save AnswerDto : {}", answerDto);
		service.saveOrUpdate(answerDto);
		return Result.buildOk("保存答题信息成功");

	}

	/**
	 * POST / : Save a answerDto.
	 *
	 * @param answerDto the HTTP answer
	 */
	@ApiOperation(value = "答题信息编辑")
	@PostMapping("/saveWithReturn")
	public Result saveWithReturn(@Valid @RequestBody AnswerDto answerDto, String nextType,
								 String nextQueId, String queType, boolean submitType) {
		log.debug("REST request to save AnswerDto : {}", answerDto);
		service.saveOrUpdate(answerDto, submitType);// 保存当前题目答题结果

		Map<String, Object> map = new HashMap<>();

		// 获取下一题答案
		QueryWrapper<Answer> queryWrapper = new QueryWrapper<Answer>();
		queryWrapper.eq("exam_record_id", answerDto.getExamRecordId());
		queryWrapper.eq("que_id", nextQueId);
		queryWrapper.eq("que_type", Long.parseLong(queType));
		Answer answerRtn = service.getOne(queryWrapper);
		map.put("answer", answerRtn);

		// 获取下一题分数
		ExaminationRecordDto recordDto = recordService.getOneDto(answerDto.getExamRecordId());
		QueryWrapper<PaperQue> paperQueQueryWrapper = new QueryWrapper<PaperQue>();
		paperQueQueryWrapper.eq("paper_id", recordDto.getPaperId());
		paperQueQueryWrapper.eq("que_id", answerDto.getQueId());
		paperQueQueryWrapper.eq("que_type", answerDto.getQueType());
		PaperQue paperQue = paperQueService.getOne(paperQueQueryWrapper);
		map.put("queScore", paperQue.getScore());

		// 查找下一题: queType 下一题type
		if("0".equals(queType)) {
			map.put("que", singleChoiceQueService.getOneDto(nextQueId));
			return Result.buildOkData(map);
		} else if("1".equals(queType)) {
			map.put("que", multipleChoiceQueService.getOneDto(nextQueId));
			return Result.buildOkData(map);
		} else if("2".equals(queType)) {
			map.put("que", judgeQueService.getOneDto(nextQueId));
			return Result.buildOkData(map);
		} else if ("3".equals(queType)) {
			map.put("que", fillQueService.getOneDto(nextQueId));
			return Result.buildOkData(map);
		} else if ("4".equals(queType)) {
			map.put("que", ojProblemsService.getOneDto(nextQueId));
			return Result.buildOkData(map);
		} else {
			return Result.buildFail("不支持的查询题目类型。");
		}
	}

	/**
	 * DELETE //:ids : delete the "ids" Answer.
	 *
	 * @param ids the id of the answer to delete
	 * @return the Result with status 200 (OK)
	 */
	@PreAuthorize("@pms.hasPermission('exam_answer_del')")
	@ApiOperation(value = "答题信息删除")
	@DeleteMapping
	public Result delete(@RequestBody Set<String> ids) {
		log.debug("REST request to delete Answer: {}", ids);
		service.removeByIds(ids);
		return Result.buildOk("删除答题信息成功");
	}

	/**
	 * GET / : Get all answer of paper.
	 *
	 * @param pm the pagination information
	 * @return the Result with status 200 (OK) and with body all answer
	 */
	@ApiOperation(value = "获取判题后试卷答案列表")
	@GetMapping("/getAnswerListInfo")
	public Result getAnswerListInfo(PageModel pm, AnswerQueryCriteria answerQueryCriteria) {
		List<AnswerDto> answerDtos = new ArrayList<>();
		IPage<Answer> answerIPage = service.findPage(pm, answerQueryCriteria);
		if (CollectionUtils.isNotEmpty(answerIPage.getRecords())) {
			answerDtos = answerIPage.getRecords().stream().map(answer -> {
				return service.convertAnswerEntity(answer);
			}).collect(Collectors.toList());
		}
		IPage<AnswerDto> answerDtoPageInfo = new PageModel<AnswerDto>();
		answerDtoPageInfo.setRecords(answerDtos);
		answerDtoPageInfo.setTotal(answerIPage.getTotal());
		answerDtoPageInfo.setCurrent(answerIPage.getCurrent());
		answerDtoPageInfo.setSize(answerIPage.getSize());

		return Result.buildOkData(answerDtoPageInfo);
	}

	/**
	 * @param examRecordId 考试记录ID
	 * @return
	 */
	@ApiOperation(value = "获取答案对象")
	@GetMapping("/getAnswerByRecordId")
	public Result getAnswerByRecordId(@Valid String examRecordId, String nextQueId, String nextQueType, String nextType) {
		log.debug("REST request to get Entity : {}", examRecordId);

		Map<String, Object> map = new HashMap<>();
		AnswerDto answerDto = null;

		if(StringUtils.isEmpty(nextQueId)) {
			answerDto = service.getAnswerByRecordId(examRecordId); // 获取考试的第一题答案
		} else {
			QueryWrapper<Answer> answerQueryWrapper = new QueryWrapper<Answer>();
			answerQueryWrapper.eq("exam_record_id", examRecordId);
			answerQueryWrapper.eq("que_id", nextQueId);
			answerQueryWrapper.eq("que_type", nextQueType);
			answerDto = service.convertAnswerEntity(service.getOne(answerQueryWrapper)); // 获取下一题答案
		}

		// 获取下一题分数
		map.put("answerDto", answerDto);

		ExaminationRecordDto recordDto = recordService.getOneDto(examRecordId);
		QueryWrapper<PaperQue> paperQueQueryWrapper = new QueryWrapper<PaperQue>();
		paperQueQueryWrapper.eq("paper_id", recordDto.getPaperId());
		paperQueQueryWrapper.eq("que_id", answerDto.getQueId());
		paperQueQueryWrapper.eq("que_type", answerDto.getQueType());
		PaperQue paperQue = paperQueService.getOne(paperQueQueryWrapper);
		map.put("queScore", paperQue.getScore());


		return  Result.buildOkData(map);
	}

	/**
	 * POST / : Save a answerDto.
	 *
	 * @param answerDto the HTTP answer
	 */
	@ApiOperation(value = "更新批改题目得分")
	@PostMapping("/markAnswer")
	public Result markAnswer(@RequestBody AnswerDto answerDto) {
		log.debug("REST request to save AnswerDto : {}", answerDto);
		int reslut = service.markAnswer(answerDto);
		if(1 == reslut) {
			return Result.buildOk("题目批改成功");
		} else {
			return Result.buildFail("题目批改失败");
		}
	}

	/**
	 * POST / : Save a answerDto.
	 *
	 * @param answerDto the HTTP answer
	 */
	@ApiOperation(value = "修改阅卷状态")
	@PostMapping("/completeMarking")
	public Result completeMarking(@RequestBody AnswerDto answerDto) {
		log.debug("REST request to save AnswerDto : {}", answerDto);
		int reslut = service.completeMarking(answerDto);
		if(1 == reslut) {
			return Result.buildOk("阅卷完成");
		} else {
			return Result.buildFail("阅卷完成失败");
		}
	}
}
